/*
 * #%L
 * Client
 * %%
 * Copyright (C) 2011 Ractoc.com
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.ractoc.opengamefinder.client.screens.controllers;

import com.ractoc.opengamefinder.api.messages.LoginMessage;
import com.ractoc.opengamefinder.api.results.MessageResultsErrorCodes;
import com.ractoc.opengamefinder.api.messages.RegisterMessage;
import com.ractoc.opengamefinder.api.results.LoginMessageResult;
import com.ractoc.opengamefinder.client.plugins.results.RegisterMessageResult;
import com.ractoc.opengamefinder.client.GuiContainer;
import com.ractoc.opengamefinder.client.plugins.nifty.NiftyPlugin;
import com.ractoc.opengamefinder.client.plugins.nifty.ScreenType;
import com.ractoc.pffj.core.PluginController;
import com.ractoc.pffj.core.PluginException;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.controls.ImageSelect;

import de.lessvoid.nifty.controls.TextField;
import de.lessvoid.nifty.render.NiftyImage;
import de.lessvoid.nifty.screen.Screen;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import org.apache.log4j.Logger;

/**
 * This is the screencontroller for the login screen. This is the main entry
 * screen for OGF.
 * 
 * @author ractoc
 * @version 0.1
 */
public class LoginScreenController extends BaseScreenController {
    
    private static Logger logger = Logger.getLogger(LoginScreenController.class.getName());

    private static final String PANEL_REGISTRATION = "registrationPanel";
    private static final String ACCOUNT_PLUGIN = "accountPlugin";
    private static final String FIELD_PASSWORD = "password";
    private static final String FIELD_REPEAT_PASSWORD = "repeatPassword";
    private static final String FIELD_NAME = "name";
    private ImageSelect avatarSelector;
    private String[] avatarList;
    private final String avatarFolder;

    /**
     * Default constructor.
     */
    public LoginScreenController() {
        this.avatarFolder = NiftyPlugin.getAvatarFolder();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void bind(final Nifty newNiftyParam, final Screen newScreenParam) {
        super.setNifty(newNiftyParam);
        super.setScreen(newScreenParam);

        avatarSelector = getScreen().findNiftyControl("avatar", ImageSelect.class);
        
        try {
            loadAvatarImages();
        }
        catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    private void loadAvatarImages() throws IOException {
        String property = getNifty().specialValuesReplace(avatarFolder);

        File avatarFolderHandler = new File(property);

        if (!avatarFolderHandler.exists()) {
            if (!avatarFolderHandler.mkdirs()) {
                throw new IOException("Unable to create avatar folder: " + avatarFolderHandler.getPath());
            }
        }

        avatarList = avatarFolderHandler.list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String filename) {
                return filename.toLowerCase().endsWith(".jpg") || filename.toLowerCase().endsWith(".png");
            }
        });
        GuiContainer.getInstance().getAssetManager().registerLocator(avatarFolderHandler.getCanonicalPath(), com.jme3.asset.plugins.FileLocator.class);
        for (String avatarFile : avatarList) {
            logger.debug("avatarFile=" + avatarFile);
            NiftyImage image = getNifty().getRenderEngine().createImage(avatarFile, false);
            avatarSelector.addImage(image);
        }
    }

    /**
     * This method is called when the player presses the quit button on the
     * login screen.
     */
    public final void quit() {
        System.exit(0);
    }

    /**
     * This method is called when the player presses the login button on the
     * login screen.
     */
    public final void login() {
        final TextField nameControl = getScreen().findNiftyControl(FIELD_NAME, TextField.class);
        final String name = nameControl.getText();
        final TextField passwordControl = getScreen().findNiftyControl(FIELD_PASSWORD, TextField.class);
        final String password = passwordControl.getText();
        final LoginMessage lMsg = new LoginMessage();
        lMsg.setName(name);
        lMsg.setPassword(password);
        LoginMessageResult lMsgResult = null;
        try {
            lMsgResult = (LoginMessageResult) PluginController.getCurrentPluginController().processMessage(
                    ACCOUNT_PLUGIN, lMsg);
        }
        catch (final PluginException e) {
            displayError(MessageResultsErrorCodes.INTERNAL_ERROR, ScreenType.LOGIN);
        }
        if (lMsgResult.getErrorCode() != MessageResultsErrorCodes.SUCCESS) {
            displayError(lMsgResult.getErrorCode(), ScreenType.LOGIN);
        }
    }

    /**
     * This method is called when the register button is pressed on hte login
     * screen.
     */
    public final void showRegistrationPanel() {
        getScreen().addPopup(getScreen().findElementByName(PANEL_REGISTRATION),
                getScreen().findElementByName(PANEL_REGISTRATION).findElementByName(FIELD_NAME));
        getScreen().findElementByName(PANEL_REGISTRATION).show();
        getScreen().findElementByName(PANEL_REGISTRATION).findElementByName(FIELD_PASSWORD).setFocus();
        getScreen().findElementByName(PANEL_REGISTRATION).findElementByName(FIELD_REPEAT_PASSWORD).setFocus();
        getScreen().findElementByName(PANEL_REGISTRATION).findElementByName(FIELD_NAME).setFocus();
    }

    /**
     * This method is called when the register button is pressed on the register
     * popup on the login screen.
     */
    public final void register() {
        try {
            final TextField nameControl = getScreen().findElementByName(PANEL_REGISTRATION).findNiftyControl(
                    FIELD_NAME, TextField.class);
            final String name = nameControl.getText();
            final TextField passwordControl = getScreen().findElementByName(PANEL_REGISTRATION).findNiftyControl(
                    FIELD_PASSWORD, TextField.class);
            final String password = passwordControl.getText();
            final TextField repeatPasswordControl = getScreen().findElementByName(PANEL_REGISTRATION).findNiftyControl(FIELD_REPEAT_PASSWORD, TextField.class);
            final String repeatPassword = repeatPasswordControl.getText();
            final RegisterMessage rMsg = new RegisterMessage();
            String avatarFile = null;
            if (avatarList.length > 0 && avatarSelector.getSelectedImageIndex() < avatarList.length) {
                avatarFile = avatarList[avatarSelector.getSelectedImageIndex()];
            }
            rMsg.setName(name);
            rMsg.setPassword(password);
            rMsg.setRepeatPassword(repeatPassword);
            rMsg.setAvatarFile(avatarFolder + File.separator + avatarFile);

            RegisterMessageResult rMsgResult = null;
            try {
                rMsgResult = (RegisterMessageResult) PluginController.getCurrentPluginController().processMessage(
                        ACCOUNT_PLUGIN, rMsg);
            }
            catch (final PluginException e) {
                displayError(MessageResultsErrorCodes.INTERNAL_ERROR, ScreenType.LOGIN);
            }
            if (rMsgResult.getErrorCode() != MessageResultsErrorCodes.SUCCESS) {
                displayError(rMsgResult.getErrorCode(), ScreenType.LOGIN);
            } else {
                // hideRegistrationPanel();
                displayScreen("lobbyScreen", ScreenType.LOGIN);
            }
        }
        catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /**
     * This method is called when the cancel button is called on the register
     * popup on the login screen.
     */
    public final void hideRegistrationPanel() {
        getScreen().closePopup(getScreen().findElementByName(PANEL_REGISTRATION), null);
        getScreen().findElementByName(PANEL_REGISTRATION).hide();
    }
}
